package com.template.template;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.template.entity.*;
import com.template.entity.markdown.Table;
import com.template.exception.RobotNotExistException;
import com.template.properties.Robot;
import com.template.properties.RobotProperty;
import com.template.request.FeiShuRequest;
import com.template.utlis.FeiShuMsgTypeEnum;
import com.template.utlis.FeiShuResponseEnum;
import com.template.utlis.FeiShuUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.template.utlis.FeiShuUtil.*;
import static com.template.utlis.StringCommons.ELEMENTS;
import static com.template.utlis.StringCommons.HEADER;

/**
 * @author wangqi
 * @date 2024-01-08 15:17
 */

public class FeishuTemplate {

    private final static Logger log = LoggerFactory.getLogger(FeishuTemplate.class);

    private final String FeiSHuUrlPrefix = "https://open.feishu.cn/open-apis/bot/v2/hook/";

    private Map<String, RobotEntity> robotEntityMap;

    private WebClient webClient;

    private void init(RobotProperty robotProperty) {
        if (robotProperty == null || robotProperty.getRobots() == null || robotProperty.getRobots().isEmpty()) {
            log.error("未配置飞书机器人相关参数");
            return;
        }
        if (robotProperty.getDisable()) {
            robotEntityMap = null;
            log.warn("-----全局已禁用飞书机器人提醒功能-----");
            return;
        }
        webClient = WebClient.builder().build();
        robotEntityMap = robotProperty.getRobots().stream().filter(Objects::nonNull).collect(Collectors.toMap(Robot::getRobotName, robot -> {
            RobotEntity robotEntity = new RobotEntity();
            robotEntity.setUrl(FeiSHuUrlPrefix + robot.getToken());
            robotEntity.setDisable(robot.getDisable());
            robotEntity.setSercret(robot.getSercret());
            return robotEntity;
        }));
    }

    public FeishuTemplate(RobotProperty robotProperty) {
        init(robotProperty);
    }

    private Mono<String> sendTableMessage(String robotName, Table table) {
        JSONObject card=new JSONObject();
        card.put(ELEMENTS,table.build());
        card.put(HEADER,table.getHeader());
        return sendMsg(robotName, card);
    }

    public void sendTableMessageUsync(String robotName, Table table){
        try {
            Mono<String> stringMono = sendTableMessage(robotName, table);
            asyncHandler(stringMono);
        } catch (Exception e) {
            log.error("发送飞书机器人Table消息失败:{}", e.getStackTrace());
        }
    }
    public String sendTableMessageBlock(String robotName, Table table){
        try {
            Mono<String> stringMono = sendTableMessage(robotName, table);
            return stringMono.block();
        } catch (Exception e) {
            log.error("发送飞书机器人Table消息失败:{}", e.getStackTrace());
            return null;
        }
    }


    private Mono<String> sendCardMessage(String robotName, JSONObject card) {
        return sendMsg(robotName, card);
    }

    public String sendCardMessageBlock(String robotName, JSONObject card) {
        try {
            Mono<String> stringMono = sendCardMessage(robotName, card);
            return stringMono.block();
        } catch (Exception e) {
            log.error("发送飞书机器人Card消息失败:{}", e.getStackTrace());
            return null;
        }
    }

    public  void sendCardMessageUsync(String robotName, JSONObject card){
        try {
            Mono<String> stringMono = sendCardMessage(robotName, card);
            asyncHandler(stringMono);
        } catch (Exception e) {
            log.error("发送飞书机器人Card消息失败:{}", e.getStackTrace());
        }
    }

    public Mono<String> sendFullTextMessage(String robotName, FullTextMessage fullTextMessage) {
        FeiShuPostContent feiShuPostContent = new FeiShuPostContent(fullTextMessage);
        return sendMsg(robotName, feiShuPostContent);
    }

    public void sendFullTextMessageAsync(String robotName, FullTextMessage fullTextMessage) {
        try {
            Mono<String> stringMono = sendFullTextMessage(robotName, fullTextMessage);
            asyncHandler(stringMono);
        } catch (Exception e) {
            log.error("发送飞书机器人富文本消息失败:{}", e.getStackTrace());
        }
    }

    public String sendFullTextMessageBlock(String robotName, FullTextMessage fullTextMessage) {
        try {
            Mono<String> stringMono = sendFullTextMessage(robotName, fullTextMessage);
            return stringMono.block();
        } catch (Exception e) {
            log.error("发送飞书机器人富文本消息失败:{}", e.getStackTrace());
            return null;
        }
    }

    public Mono<String> sendMsgText(String robotName, TextMessage textMessage) throws RobotNotExistException {
        String content = buildAtTextContent(textMessage.getContent(), textMessage.getIdList(), textMessage.getAtAll());
        FeiShuTextContent feiShuTextContent = new FeiShuTextContent();
        feiShuTextContent.setText(content);
        return sendMsg(robotName, feiShuTextContent);
    }

    public String sendTextMessageBlock(String robotName, TextMessage textMessage) {
        try {
            Mono<String> stringMono = sendMsgText(robotName, textMessage);
            return stringMono.block();
        } catch (Exception e) {
            log.error("发送飞书机器人文本消息失败:{}", e.getStackTrace());
            return null;
        }
    }

    public void sendTextMessageAsync(String robotName, TextMessage textMessage) {
        try {
            Mono<String> stringMono = sendMsgText(robotName, textMessage);
            asyncHandler(stringMono);
        } catch (Exception e) {
            log.error("发送飞书机器人文本消息失败:{}", e.getStackTrace());
        }
    }

    private void asyncHandler(Mono<String> stringMono) {
        stringMono.subscribe((response) -> {
            if (!StringUtils.isEmpty(response)) {
                if (FeiShuResponseEnum.SUCCESS.getCode().equals(JSON.parseObject(response).getString(CODE))) {
                    log.info("飞书机器人文本消息发送成功");
                } else {
                    log.error("飞书机器人文本消息发送失败:{}" + response);
                }
            }
        }, (error) -> {
            log.error("飞书机器人消息发送失败");
        });
    }

    private Mono<String> sendMsg(String robotName, JSONObject   card) {
        RobotEntity robotEntity = robotEntityMap.get(robotName);
        if (robotEntity == null) {
            log.warn("不存在名为{}的飞书机器任配置", robotName);
            throw new RobotNotExistException();
        }
        FeiShuRequest feiShuRequest = new FeiShuRequest();
        feiShuRequest.setMsgType(FeiShuMsgTypeEnum.CARD.getMsgType());
        long l = System.currentTimeMillis() / 1000;
        if (!StringUtils.isEmpty(robotEntity.getSercret())) {
            String sign = FeiShuUtil.GenSign(robotEntity.getSercret(), l);
            if (sign == null) {
                return null;
            } else {
                feiShuRequest.setSign(sign);
            }
        }
        feiShuRequest.setTimestamp("" + l);
        feiShuRequest.setCard(card);
        return webClient.post().uri(robotEntity.getUrl()).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(feiShuRequest)).retrieve().bodyToMono(String.class);

    }

    private Mono<String> sendMsg(String robotName, FeiShuContent content) {
        RobotEntity robotEntity = robotEntityMap.get(robotName);
        if (robotEntity == null) {
            log.warn("不存在名为{}的飞书机器任配置", robotName);
            throw new RobotNotExistException();
        }
        FeiShuRequest feiShuRequest = new FeiShuRequest();
        feiShuRequest.setMsgType(content.getMsgType());
        long l = System.currentTimeMillis() / 1000;
        if (!StringUtils.isEmpty(robotEntity.getSercret())) {
            String sign = FeiShuUtil.GenSign(robotEntity.getSercret(), l);
            if (sign == null) {
                return null;
            } else {
                feiShuRequest.setSign(sign);
            }
        }
        feiShuRequest.setTimestamp("" + l);
        feiShuRequest.setContent(content);
        return webClient.post().uri(robotEntity.getUrl()).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(feiShuRequest)).retrieve().bodyToMono(String.class);
    }


}
